#include <iostream>
#include <string.h>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
using std::istream;
using std::ostream;
using std::vector;
class String 
{
public:
    //构造函数
    String():_pstr(nullptr){
        //cout << "String()" <<endl;
    }
    String(const char * pstr)
    :_pstr(new char[strlen(pstr)+1]()){
        strcpy(_pstr,pstr);
        //cout << "String(const char *)" << endl;
    }
    String(const String & s)
    :_pstr(new char[strlen(s._pstr)+1]()){
        strcpy(_pstr,s._pstr);
        //cout << "String(const String &)" << endl;
    }
    //析构函数
    ~String(){
        if(_pstr){
            delete [] _pstr;
            _pstr = nullptr;
        }
        //cout << "~String()" << endl;
    }
    //=运算符重载
    String &operator=(const String & rhs){
        if(this != &rhs){
            delete [] _pstr;
            _pstr = new char[strlen(rhs._pstr)+1]();
            strcpy(_pstr,rhs._pstr);
        }
        return *this;
    }
    String &operator=(const char * pstr){
        String temp(pstr);
        *this = temp;
        return *this;
    }
    // += 运算符重载
    String &operator+=(const String & rhs){
        char *temp = new char[strlen(_pstr) + strlen(rhs._pstr) + 1]();
        strcpy(temp,_pstr);
        strcat(temp,rhs._pstr);
        delete [] _pstr;
        _pstr = temp;
        return *this;
    }

    String &operator+=(const char * s){
        String temp(s);
        *this += temp;
        return *this;
    }
	
    char &operator[](std::size_t index){
        if(index >= size()){
            static char nullchar = '\0';
            return nullchar;
        }
        return _pstr[index];
    }
    const char &operator[](std::size_t index) const{
        if(index >= size()){
            static char nullchar = '\0';
            return nullchar;
        }
        return _pstr[index];

    }
	
    std::size_t size() const{
        return strlen(_pstr);
    }
    const char* c_str() const{
        return _pstr;
    }
	
    //重载+运算符
    friend String operator+(const String & lhs, const String & rhs);
    friend String operator+(const String & lhs, const char * s);
    friend String operator+(const char * pstr, const String & rhs);

	friend bool operator==(const String &, const String &);
	friend bool operator!=(const String &, const String &);
	
	friend bool operator<(const String &, const String &);
	friend bool operator>(const String &, const String &);
	friend bool operator<=(const String &, const String &);
	friend bool operator>=(const String &, const String &);
	
	friend std::ostream &operator<<(std::ostream &os, const String &s);
	friend std::istream &operator>>(std::istream &is, String &s);

    void print(){
        cout << _pstr <<endl;
    }
private:
	char * _pstr;
};

String operator+(const String & lhs, const String & rhs){
    char *temp = new char[strlen(lhs._pstr) + strlen(rhs._pstr) + 1]();
    strcpy(temp,lhs._pstr);
    strcat(temp,rhs._pstr);
    String s(temp);
    return s;
}
String operator+(const String & lhs, const char * pstr){
    char *temp = new char[strlen(lhs._pstr) + strlen(pstr) + 1]();
    strcpy(temp,lhs._pstr);
    strcat(temp,pstr);
    String s(temp);
    return s;
     
}
String operator+(const char * pstr, const String & rhs){
    char *temp = new char[strlen(pstr) + strlen(rhs._pstr) + 1]();
    strcpy(temp,pstr);
    strcat(temp,rhs._pstr);
    String s(temp);
    return s;

}
bool operator==(const String & s1, const String & s2){
    return strcmp(s1._pstr,s1._pstr)==0;
}
bool operator!=(const String & s1, const String & s2){
    return strcmp(s1._pstr,s2._pstr)!=0;
}
bool operator<(const String & s1, const String & s2){
    return strcmp(s1._pstr,s2._pstr)<0;
}
bool operator>(const String & s1, const String & s2){
    return strcmp(s1._pstr,s2._pstr)>0;
}
bool operator<=(const String & s1, const String & s2){
    return strcmp(s1._pstr,s2._pstr)<=0;
}
bool operator>=(const String & s1, const String & s2){
    return strcmp(s1._pstr,s2._pstr)>=0;
}
ostream &operator<<(ostream &os, const String &s){
    os << s._pstr;
    return os;
}
istream &operator>>(istream &is, String &s){
    if(s._pstr){
        delete [] s._pstr;
    }
    vector<char> array;
    char c;
    while((c = is.get()) != '\n'){
        array.push_back(c);
    }
    char *temp = new char[array.size() + 1]();
    for(size_t i = 0; i<array.size();++i){
        temp[i] = array[i];
    }
    s._pstr = temp;
    return is;
}
void test(){
    String s1;
    String s2("hello");
    String s3(s2);
}
void test2(){
    String s1("hello");
    String s2("world");
    s2 = s1;
    s2.print();
    s1 = "aaaaaa";
    s1.print();
}
void test3(){
    String s("hello");
    String s2("world");
    s += s2;
    s.print();
    s += "nihao";
    s.print();
}
void test4(){
    String s1("hello");
    String s2("world");
    String s3 = s1+s2;
    s3.print();
    s3 = s1 + "aaaaa";
    s3.print();
    s2 = "bbbbbb" + s3;
    s2.print();
}

void test5(){
    String s1("hello");
    String s2("hello");
    String s3("world");
    if(s1 == s2){
        cout << "s1 == s2" <<endl;
    }
    if(s1 < s3){
        cout << "s1 < s3" << endl;
    }
}
void test6(){
    String s1("hello");
    cout << s1 <<endl;
    cin >> s1;
    cout << s1 << endl;
}


int main()
{
    test6();
    return 0;
}

